// file: src/main/java/org/example/backend/security/JwtAuthenticationFilter.java
package org.example.backend.security;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.backend.util.JwtUtil;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final UserDetailsService userDetailsService;
    private final JwtUtil jwtUtil;

    public JwtAuthenticationFilter(UserDetailsService userDetailsService, JwtUtil jwtUtil) {
        this.userDetailsService = userDetailsService;
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        System.out.println("JwtAuthenticationFilter doFilterInternal called for URL: " + request.getRequestURL());

        final String authorizationHeader = request.getHeader("Authorization");
        System.out.println("Authorization header: " + authorizationHeader);

        String username = null;
        String jwt = null;

        // 改进判断逻辑，处理可能的空格问题
        if (authorizationHeader != null && authorizationHeader.trim().startsWith("Bearer ")) {
            jwt = authorizationHeader.trim().substring(7);
            System.out.println("Extracted JWT: " + jwt);

            // 添加长度检查
            if (jwt != null && !jwt.isEmpty()) {
                try {
                    username = jwtUtil.getUsernameFromToken(jwt);
                    System.out.println("Extracted username from token: " + username);
                } catch (Exception e) {
                    System.out.println("Error extracting username from token: " + e.getMessage());
                }
            }
        } else {
            System.out.println("No valid Authorization header found");
            if (authorizationHeader != null) {
                System.out.println("Authorization header length: " + authorizationHeader.length());
                System.out.println("Authorization header starts with 'Bearer ': " + authorizationHeader.startsWith("Bearer "));
            }
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            try {
                System.out.println("Loading user details for: " + username);
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                System.out.println("Loaded user details for: " + username);

                if (jwtUtil.validateToken(jwt, username)) {
                    System.out.println("Token validated successfully");
                    // 获取角色信息
                    String role = jwtUtil.getRoleFromToken(jwt);
                    System.out.println("Extracted role from token: " + role);

                    // 确保角色有 ROLE_ 前缀
                    String roleWithPrefix = role.startsWith("ROLE_") ? role : "ROLE_" + role;

                    // 创建带角色的认证对象
                    Collection<? extends GrantedAuthority> authorities =
                            Collections.singletonList(new SimpleGrantedAuthority(roleWithPrefix));

                    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                            userDetails, null, authorities);
                    authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authToken);
                    System.out.println("Authentication set in SecurityContext with authorities: " + authorities);
                } else {
                    System.out.println("Token validation failed");
                }
            } catch (Exception e) {
                System.out.println("Error loading user details: " + e.getMessage());
                e.printStackTrace();
            }
        } else {
            System.out.println("Username is null or authentication already exists");
        }

        filterChain.doFilter(request, response);
    }
}
